package stackElimination;
import java.util.concurrent.atomic.AtomicReference;
import locks.Backoff;

interface MyStack<T> {
    void push(T value);

    T pop() throws Exception;
}

class LockFreeStack<T> {
    private final AtomicReference<Node<T>> top = new AtomicReference<Node<T>>(null);
    
    static final int MIN_DELAY = 0;
    static final int MAX_DELAY = 0;

    Backoff backoff;


    public LockFreeStack(int min_delay, int mac_delay) {
        backoff = new Backoff(min_delay, mac_delay);
    }

    boolean tryPush(Node<T> value) {
        Node<T> oldTop = top.get();
        value.next = oldTop;
        return (top.compareAndSet(oldTop, value));
    }

    Node<T> tryPop() {
        Node<T> oldTop = top.get();
        Node<T> newTop = oldTop.next;
        if (top.compareAndSet(oldTop, newTop)) {
            return oldTop;
        } else {
            return null;
        }
    }
}

class Node<T> {
    T value;
    Node<T> next;

    Node(T value) {
        this.value = value;
    }
}

class RangePolicy {
    protected final int exchangerCapacity;
    protected int eliminationSuccess = 0;
    protected int eliminationTimeout = 0;

    RangePolicy(int exchangerCapacity) {
        this.exchangerCapacity = exchangerCapacity;
    }

    void recordEliminationSuccess() {
        eliminationSuccess++;
    }

    void recordEliminationTimeout() {
        eliminationTimeout++;
    }

    int getRange() {
        return this.exchangerCapacity;
    }
}